/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package javaapplication1;

import java.util.HashMap;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.MatchResult;

/**
 *
 * @author Oren
 */
public class ProgramCommandExecutor {
    private Robot rbt ;
    private HashMap<String,Command> hm ;
    private Boxes bx;

    private Scanner scn;
    private MatchResult result ;

    private void add(Command c){
        hm.put(c.getKey(), c);
    }


    // commands Ctor
    public ProgramCommandExecutor(){

        hm = new HashMap<String,Command>();

        add(new Move());
        add(new Pickup());
        add(new Stop());
        add(new PutBoxDown());

 }

    private class  Move implements Command{
        String format="(\\d+) Move speed ([-]*\\d+) heading ([-]*\\d+)";
        public void run() {
            int speed=Integer.parseInt(scn.match().group(2));
            int heading=Integer.parseInt(scn.match().group(3));

            rbt.move(speed, heading);
            
        }

        public String getFormat() {
            return format;
        }

        public String getKey() {
            return "Move";
        }

    }

    private class Pickup implements Command{
    String format="(\\d+) Pickup (\\w+)";
        public synchronized void run() {
            String boxname=scn.match().group(2);
            if (bx.getBox(boxname)==null)
            {
                System.out.println("Error: no box by that name.");
                return ;
            }
            
            if (!rbt.pickupBox(bx.getBox(boxname)))
                System.out.println("Error: "+rbt.getName()+" is unable to pickup "+boxname);

            
        }

        public String getFormat() {
            return format;
        }

        public String getKey() {
            return "Pickup";
        }

    }

    private class Stop implements Command{
    String format="(\\d+) Stop";
        public void run() {
            rbt.stop();
        }

        public String getFormat() {
            return format;
        }

        public String getKey() {
            return "Stop";
        }

    }

    private class PutBoxDown implements Command{
    String format="(\\d+) PutBoxDown";
        public synchronized void run() {
            if (!rbt.putdownBox())
                System.out.println("Error: "+rbt.getName()+" has no box.");

        }

        public String getFormat() {
            return format;
        }

        public String getKey() {
            return "PutBoxDown";
        }

    }

   public void runCommand(String cmd,Robot robot,Boxes bx){
       rbt = robot;
       this.bx = bx;
       // TODO ignore the first word becuase it is time
        String words[]=cmd.split(" ");
        if (hm.get(words[1])==null)
            System.out.println("Error: command not found.");
        else if (decoder(cmd , hm.get(words[1]).getFormat()))
            try {
            hm.get(words[1]).run();
        } catch (Exception ex) {
            Logger.getLogger(ProgramCommandExecutor.class.getName()).log(Level.SEVERE, null, ex);
        }
        else System.out.println("Error: command not found.");
    }


     public boolean decoder(String cmd, String format)
     {
         if(cmd.matches(format)){// if the command we got fits the correct format
             scn=new Scanner(cmd);
             scn.findInLine(format);// scans according to the format
             result = scn.match();
             return true;
         }
         return false;
     }



}
